1 module hunt.cache.redis;
2 
3 import hunt.cache.cache;
4 import hunt.cache.nullable;
5 import hunt.cache.store;
6 
7 import std.conv;
8 import std.string;
9 
10 version(SUPPORT_REDIS):
11 
12 import redis;
13 
14 class RedisCache
15 {
16 	Nullable!V get(V)(string key)
17 	{
18 		synchronized(this)
19 		{
20 			string data = _redis.send!string("get" , key);
21 			return DeserializeToObject!V(cast(byte[])data);
22 		}
23 	}
24 
25 	Nullable!V[string] getall(V)(string[] keys)
26 	{
27 		synchronized(this){
28 			Nullable!V[string] mapv;
29 			if( keys.length == 0)
30 				return mapv;
31 
32 			Response r = _redis.send("mget" , keys);
33 
34 			foreach(i , v ; r.values)
35 			{
36 				mapv[keys[i]] = DeserializeToObject!V(cast(byte[])v);
37 			}
38 
39 			return mapv;
40 		}
41 	}
42 
43 	bool containsKey(string key)
44 	{
45 		synchronized(this)
46 		{
47 			return _redis.send!bool("exists" , key);
48 		}
49 	}
50 	
51 	void put(V)(string key ,  V v , uint expired)
52 	{
53 		synchronized(this)
54 		{
55 			if( expired == 0)
56 				_redis.send("set" , key , cast(string)SerializeToByte(v));
57 			else
58 				_redis.send("setex" , key , expired , cast(string)SerializeToByte(v));
59 		}
60 	}
61 
62 	bool putifAbsent(V)(string key ,  V v)
63 	{
64 		synchronized(this)
65 		{
66 				return _redis.send!bool("setnx" , key , cast(string)SerializeToByte(v)) == 1;		
67 		}
68 
69 	}
70 
71 	void putAll(V)( V[string] maps , uint expired)
72 	{
73 		synchronized(this){
74 			if(maps.length == 0)
75 			return;
76 
77 			if(expired == 0)
78 			{
79 				string cmds = "mset ";
80 				foreach(k , v ; maps)
81 				{
82 					cmds ~= k ~ " " ~ cast(string)SerializeToByte(v) ~ " ";
83 				}
84 				_redis.send(cmds);
85 			}
86 			else
87 			{
88 				string[] cmds;
89 				foreach( k ,v ; maps){
90 					cmds ~= "setex " ~ k ~ " " ~ to!string(expired) ~ " " ~ cast(string)SerializeToByte(v);
91 				}
92 
93 				_redis.pipeline(cmds);
94 			}
95 		}
96 	}
97 	
98 	bool remove(string key)
99 	{
100 		synchronized(this)
101 		{
102 			return _redis.send!bool("del" , key);
103 		}
104 	}
105 
106 	void removeAll(string[] keys)
107 	{
108 		synchronized(this)
109 		{
110 			if( keys.length == 0)
111 			return ;
112 
113 			string[] cmds;
114 			foreach(k ; keys){
115 				cmds ~= "del " ~ k;
116 			}
117 			_redis.pipeline(cmds);
118 		}
119 	}
120 
121 	void clear()
122 	{
123 		synchronized(this)
124 		{
125 			_redis.send("flushdb");
126 		}
127 	}
128 
129 	this(string args)
130 	{
131 		if(args == null)
132 			args = "127.0.0.1:6379";
133 
134 		auto hp = args.split(":");
135 		_redis = new Redis(hp[0] , to!ushort(hp[1]));
136 	}
137 
138 protected:
139 	Redis _redis;
140 }